package cn.demoncat.util.es.entity;

import cn.demoncat.util.lang.ArrayUtil;
import cn.demoncat.util.lang.JsonUtil;
import cn.demoncat.util.lang.LocalDateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.plugins.PluginInfo;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 节点信息
 * 
 * @author 延晓磊
 *
 * @since 2019年12月27日
 */
public class NodeInfo {

	// 节点名
	private String name;
	// 主机名（IP）
	private String hostname;
	// 版本
	private String version;
	// 角色：主、从、数据
	private List<String> roles;
	// 配置文件
	private Object settings;
	
	// 系统名称
	private String osName;
	
	// JDK版本
	private String jdkVersion;
	// JVM启动时间
	private LocalDateTime startTime;
	// JVM内存：byte
	private Long memHeapInit;
	private Long memHeapMax;
	private Long memNonHeapInit;
	private Long memNonHeapMax;
	private Long memDirectMax;

	// HTTP 绑定地址（0.0.0.0允许公网访问）
	private String boundAddress;
	// HTTP 发布地址
	private String publishAddress;
	
	// 插件
	private List<String> plugins;
	
	/**
	 * 转换
	 * 
	 * @param response
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月27日
	 */
	public static List<NodeInfo> parse(NodesInfoResponse response) {
		List<NodeInfo> nodes = new ArrayList<>(response.getNodes().size());
		NodeInfo node;
		for (org.elasticsearch.action.admin.cluster.node.info.NodeInfo info : response.getNodes()) {
			node = new NodeInfo();
			// 节点信息
			node.setName(info.getNode().getName());
			node.setHostname(info.getHostname());
			node.setVersion(info.getVersion().toString());
			node.setRoles(null);
			node.setSettings(info.getSettings());
			
			// 系统信息
			node.setOsName(info.getOs().getPrettyName());
			
			// JVM信息
			node.setJdkVersion(info.getJvm().getVersion());
			node.setStartTime(LocalDateUtil.toLocalDateTime(info.getJvm().getStartTime()));
			
			// JVM内存
			node.setMemDirectMax(info.getJvm().getMem().getDirectMemoryMax().getBytes());
			node.setMemHeapInit(info.getJvm().getMem().getHeapInit().getBytes());
			node.setMemHeapMax(info.getJvm().getMem().getHeapMax().getBytes());
			node.setMemNonHeapInit(info.getJvm().getMem().getNonHeapInit().getBytes());
			node.setMemNonHeapMax(info.getJvm().getMem().getNonHeapMax().getBytes());
			
			// HTTP信息
			node.setPublishAddress(info.getHttp().getAddress().publishAddress().toString());
			node.setBoundAddress(ArrayUtil.toString(info.getHttp().getAddress().boundAddresses()));
			
			// 插件
			node.setPlugins(info.getPlugins().getPluginInfos().stream().map(PluginInfo::getName).collect(Collectors.toList()));
			nodes.add(node);
		}
		return nodes;
	}
	
	/**
	 * 转换
	 * 
	 * @param response
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年9月6日
	 */
	public static List<NodeInfo> parse(String response) {
		JSONObject nodes = JsonUtil.parseObject(response).getJSONObject("nodes");
		JSONObject node;
		JSONObject obj;
		JSONArray arr;
		List<NodeInfo> list = new ArrayList<>(nodes.size());
		NodeInfo info;
		for (String key : nodes.keySet()) {
			node = nodes.getJSONObject(key);
			info = new NodeInfo();
			// 节点信息
			info.setName(node.getString("name"));
			info.setHostname(node.getString("ip"));
			info.setVersion(node.getString("version"));
			info.setRoles(node.getJSONArray("roles").stream().map(StringUtils::toString).collect(Collectors.toList()));
			info.setSettings(node.getJSONObject("settings"));
			
			// 系统信息
			info.setOsName(node.getJSONObject("os").getString("pretty_name"));
			
			// JVM信息
			obj = node.getJSONObject("jvm");
			info.setJdkVersion(obj.getString("version"));
			info.setStartTime(LocalDateUtil.toLocalDateTime(obj.getLong("start_time_in_millis")));
			
			// JVM内存
			obj = obj.getJSONObject("mem");
			info.setMemDirectMax(obj.getLong("direct_max_in_bytes"));
			info.setMemHeapInit(obj.getLong("heap_init_in_bytes"));
			info.setMemHeapMax(obj.getLong("heap_max_in_bytes"));
			info.setMemNonHeapInit(obj.getLong("non_heap_init_in_bytes"));
			info.setMemNonHeapMax(obj.getLong("non_heap_max_in_bytes"));
			
			// HTTP信息
			obj = node.getJSONObject("http");
			info.setBoundAddress(obj.getString("bound_address"));
			info.setPublishAddress(obj.getString("publish_address"));
			
			// 插件
			arr = node.getJSONArray("plugins");
			info.setPlugins(new ArrayList<>());
			for (int i = 0; i < arr.size(); i++) {
				info.getPlugins().add(arr.getJSONObject(i).getString("name"));
			}
			list.add(info);
		}
		return list;
	}

	public String getHostname() {
		return hostname;
	}

	public void setHostname(String hostname) {
		this.hostname = hostname;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Long getMemHeapInit() {
		return memHeapInit;
	}

	public void setMemHeapInit(Long memHeapInit) {
		this.memHeapInit = memHeapInit;
	}

	public Long getMemHeapMax() {
		return memHeapMax;
	}

	public void setMemHeapMax(Long memHeapMax) {
		this.memHeapMax = memHeapMax;
	}

	public Long getMemNonHeapInit() {
		return memNonHeapInit;
	}

	public void setMemNonHeapInit(Long memNonHeapInit) {
		this.memNonHeapInit = memNonHeapInit;
	}

	public Long getMemNonHeapMax() {
		return memNonHeapMax;
	}

	public void setMemNonHeapMax(Long memNonHeapMax) {
		this.memNonHeapMax = memNonHeapMax;
	}

	public Long getMemDirectMax() {
		return memDirectMax;
	}

	public void setMemDirectMax(Long memDirectMax) {
		this.memDirectMax = memDirectMax;
	}

	public LocalDateTime getStartTime() {
		return startTime;
	}

	public void setStartTime(LocalDateTime startTime) {
		this.startTime = startTime;
	}

	public List<String> getRoles() {
		return roles;
	}

	public void setRoles(List<String> roles) {
		this.roles = roles;
	}

	public Object getSettings() {
		return settings;
	}

	public void setSettings(Object settings) {
		this.settings = settings;
	}

	public String getOsName() {
		return osName;
	}

	public void setOsName(String osName) {
		this.osName = osName;
	}

	public String getJdkVersion() {
		return jdkVersion;
	}

	public void setJdkVersion(String jdkVersion) {
		this.jdkVersion = jdkVersion;
	}

	public String getBoundAddress() {
		return boundAddress;
	}

	public void setBoundAddress(String boundAddress) {
		this.boundAddress = boundAddress;
	}

	public String getPublishAddress() {
		return publishAddress;
	}

	public void setPublishAddress(String publishAddress) {
		this.publishAddress = publishAddress;
	}

	public List<String> getPlugins() {
		return plugins;
	}

	public void setPlugins(List<String> plugins) {
		this.plugins = plugins;
	}

	

}
